package rest

import (
	"context"
	"fmt"
	"gitee.com/gaodihu/gsf/core/logx"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
)

type engine struct {
	conf           RestConf
	featuredRoutes []featuredRoutes
	middlewares    []gin.HandlerFunc
}

func NewEngine(c RestConf) *engine {
	srv := &engine{
		conf: c,
	}
	return srv
}

func (s *engine) AddRoutes(r featuredRoutes) {
	s.featuredRoutes = append(s.featuredRoutes, r)
}
func (s *engine) Start() {
	var err error
	g := s.bind()

	srv := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", s.conf.Host, s.conf.Port),
		Handler: g,
	}

	// 等待中断信号以优雅地关闭服务器（设置 5 秒的超时时间）
	quit := make(chan os.Signal, 1)
	signal.Notify(quit,os.Interrupt, syscall.SIGTERM)
	go func() {
		// 服务连接
		if len(s.conf.CertFile) > 0 &&
			len(s.conf.KeyFile) > 0 {
			err = srv.ListenAndServeTLS(s.conf.CertFile, s.conf.KeyFile)
		} else {
			err = srv.ListenAndServe()
		}
		if err != http.ErrServerClosed {
			logx.ErrorWithStack(err)
			quit <- syscall.SIGTERM
		}
	}()

	<-quit
	log.Println("Shutdown Server ...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}

func (s *engine) bind() *gin.Engine {
	if len(s.conf.Mode) > 0 {
		gin.SetMode(s.conf.Mode)
	}
	g := gin.New()
	if s.conf.Verbose {
		g.Use(gin.Logger())
	}

	g.Use(gin.Recovery())

	if len(s.middlewares) > 0 {
		g.Use(s.middlewares...)
	}

	for _, f := range s.featuredRoutes {
		urlPrefix := f.urlPrefix
		group := g.Group(urlPrefix)
		if len(f.middlerwares) > 0 {
			group.Use(f.middlerwares...)
		}
		for _, r := range f.routes {
			group.Handle(r.Method, r.Path, r.Handler)
		}
	}
	return g
}

func (s *engine) isSecure() bool {
	if len(s.conf.CertFile) > 0 &&
		len(s.conf.KeyFile) > 0 {
		return true
	}
	return false
}
